/**
 * 
 */
package qy.jalgotrade.talibext;

import org.apache.commons.lang3.tuple.Pair;

import com.tictactec.ta.lib.CoreAnnotated;
import com.tictactec.ta.lib.MInteger;
import com.tictactec.ta.lib.RetCode;

import qy.jalgotrade.dataseries.DataSeries;
import qy.jalgotrade.utils.PySpecs;

/**
 * @author c-geo
 *
 */
public final class Indicator {

	private static CoreAnnotated taLib = new CoreAnnotated();

	/**
	 * TA_MAX - Highest value over a specified period:
	 * 
	 * @param ds
	 * @param count      values used (recent) count in ds;
	 * @param timePeriod (optional): Number of period, [2, 100000] (default: 30)
	 * @return
	 * @see com.tictactec.ta.lib.CoreAnnotated#max(int, int, double[], int, MInteger, MInteger,
	 *      double[])
	 */
	public static Pair<RetCode, Double> MAX(DataSeries<Double> ds, int count, int timePeriod) {

		int startIdx;
		int endIdx = ds.__len__() - 1;
		startIdx = endIdx - count + 1;
		double[] inReal = (double[]) PySpecs.toPrimitiveArray(ds, 0, ds.__len__());
		int optInTimePeriod = timePeriod;
		MInteger outBegIdx = new MInteger();
		MInteger outNBElement = new MInteger();
		double[] outReal = new double[endIdx - startIdx + 1];

		RetCode taLibRet = taLib.max(startIdx, endIdx, inReal, optInTimePeriod, outBegIdx, outNBElement, outReal);
		if (taLibRet == RetCode.Success) {
			return Pair.of(taLibRet, outReal[outNBElement.value - 1]);
		} else {
			return Pair.of(taLibRet, Double.NaN);
		}
	}

	/**
	 * TA_MIN - Lowest value over a specified period:
	 * 
	 * @param ds
	 * @param count      values used (recent) count in ds;
	 * @param timePeriod (optional): Number of period, [2, 100000] (default: 30)
	 * @return
	 * @see com.tictactec.ta.lib.CoreAnnotated#min(int, int, double[], int, MInteger, MInteger,
	 *      double[])
	 */
	public static Pair<RetCode, Double> MIN(DataSeries<Double> ds, int count, int timePeriod) {

		int startIdx;
		int endIdx = ds.__len__() - 1;
		startIdx = endIdx - count + 1;
		double[] inReal = (double[]) PySpecs.toPrimitiveArray(ds, 0, ds.__len__());
		int optInTimePeriod = timePeriod;
		MInteger outBegIdx = new MInteger();
		MInteger outNBElement = new MInteger();
		double[] outReal = new double[endIdx - startIdx + 1];

		RetCode taLibRet = taLib.min(startIdx, endIdx, inReal, optInTimePeriod, outBegIdx, outNBElement, outReal);
		if (taLibRet == RetCode.Success) {
			return Pair.of(taLibRet, outReal[outNBElement.value - 1]);
		} else {
			return Pair.of(taLibRet, Double.NaN);
		}
	}

	/**
	 * 
	 */
	private Indicator() {

	}
}
